package com.tiger.admin;

import com.tiger.common.IpToAddress;
import com.tiger.mongodb.entity.BackendLog;
import com.tiger.mongodb.repository.BackendLogRepository;
import com.tiger.utils.IpUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.Instant;
import java.util.Arrays;

@Aspect
@Component
public class LoggingAspect {

    @Autowired
    private BackendLogRepository backendLogRepository;

    @Autowired
    private IpToAddress ipToAddress;

//    @Before("execution(* com.tiger.admin.http.*.*.*(..))")
//    public void beforeAdvice(JoinPoint joinPoint) {
//
//        //logger.info("Method {} with arguments {} is called", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
//    }

//    @AfterReturning(pointcut = "execution(* com.tiger.admin.http.*.*.*(..))", returning = "result")
//    public void afterReturningAdvice(JoinPoint joinPoint, Object result){
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        if (attributes == null) return;
//
//        HttpServletRequest request = attributes.getRequest();
//
//
//        String method = request.getMethod();
//        if(method.equals("DELETE") || method.equals("PUT")) {
//            saveLog(joinPoint, result, request);
//        }
//    }

    @AfterReturning(pointcut = "@annotation(com.tiger.admin.SaveOperateLog)", returning = "result")
    public void afterReturningAdviceBySaveLog(JoinPoint joinPoint, Object result){
        SaveOperateLog saveLog = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(SaveOperateLog.class);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) return;

        HttpServletRequest request = attributes.getRequest();


        saveLog(saveLog.value(), joinPoint, result, request);
    }

    private void saveLog(String action, JoinPoint joinPoint, Object result, HttpServletRequest request) {

        //String api = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);

        Instant now = Instant.now();

        BackendLog log = new BackendLog();

        log.setUrl(request.getRequestURI());
        log.setTime(now.getEpochSecond());
        log.setIp(IpUtil.getIpAddr(request));
        log.setBrowser(request.getHeader("User-Agent"));
        log.setMemberId((long) request.getAttribute("memberId"));
        log.setAction(action);

        String address = ipToAddress.getAddress(log.getIp());
        if(address != null) {
            log.setLocation(address);
        }

        log.setData(Arrays.toString(joinPoint.getArgs()));
        log.setResult(result.toString());

        backendLogRepository.save(log);

    }
}
